package shemes;

import java.awt.Point;
import java.util.ArrayList;

import gui.*;
import components.*;

public class Adr1 {

    private static IntToInt IBUS2ToGPRAR;
    private static REG GPRAR;
    private static GPR GPRegs;
    private static TSB TSBGPRout2;
    private static REG SP;
    private static TSB TSBSPout1;
    private static ADD ADDadr;
    private static REG CW;
    private static TSB TSBADDout1;
    private static GuiScheme gui;

    public static GuiScheme getGui() {
        return gui;
    }

    public static void init() {
        IBUS2ToGPRAR = new IntToInt(16, 5,false,false);

        GPRAR = new REG(1, "GPRAR");
        GPRAR.getOut(0).setIsInt();
        GPRAR.getOut(0).setNumOfLines(5);

        GPRegs = new GPR(32);
        GPRegs.getOut(0).setNumOfLines(16);

        TSBGPRout2 = new TSB();
        TSBGPRout2.getOut(0).setNumOfLines(16);

        SP = new REG(1, "SP");
        SP.getOut(0).setIsInt();
        SP.getOut(0).setNumOfLines(16);
        SP.initVal(4096);//1000h

        TSBSPout1 = new TSB();
        TSBSPout1.getOut(0).setNumOfLines(16);

        ADDadr = new ADD();
        ADDadr.getOut(0).setIsInt();
        ADDadr.getOut(0).setNumOfLines(16);

        CW = new REG(1, "PR");
        CW.getOut(0).setIsInt();
        CW.getOut(0).setNumOfLines(16);

        TSBADDout1 = new TSB();
        TSBADDout1.getOut(0).setNumOfLines(16);

    }

    public static void connect() {
        IBUS2ToGPRAR.setInputPin(0, Bus1.IBUS2());

        GPRAR.setInputPin(0, IBUS2ToGPRAR.getOut(0));
        GPRAR.setPinLd(Oper1.ldGPRAR());
        GPRAR.setPinInc(Oper1.incGPRAR());

        GPRegs.setAdressPin(GPRAR.getOut(0));
        GPRegs.setInputDataPin(Bus1.IBUS2());
        GPRegs.setWrite(Oper1.wrGPR());
        GPRegs.setRead(new Pin(true));

        TSBGPRout2.setInputPin(0, GPRegs.getOut(0));
        TSBGPRout2.setCtrl(Oper1.GPRout2());
        Bus1.addOnIBUS2(TSBGPRout2.getOut(0));

        SP.setInputPin(0, Bus1.IBUS2());
        SP.setPinInc(Oper1.incSP());
        SP.setPinDec(Oper1.decSP());
        SP.setPinLd(Oper1.ldSP());

        TSBSPout1.setInputPin(0, SP.getOut(0));
        TSBSPout1.setCtrl(Oper1.SPout1());
        Bus1.addOnIBUS1(TSBSPout1.getOut(0));

        CW.setInputPin(0, Bus1.IBUS1());
        CW.setPinLd(Oper1.ldCW());

        ADDadr.setPinA(CW.getOut(0));
        ADDadr.setPinB(Bus1.IBUS2());

        TSBADDout1.setInputPin(0, ADDadr.getOut(0));
        TSBADDout1.setCtrl(Oper1.ADDout1());
        Bus1.addOnIBUS1(TSBADDout1.getOut(0));

    }

    public static void gui() {
        GuiLine line; // Pomocna promenljiva
        gui = new GuiScheme("src/images/Adr1.png");

        ArrayList<ArrayList<Point>> sections;
        ArrayList<Point> points;



        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(105, 51));
        points.add(new Point(105, 645));
        sections.add(points);
        points = new ArrayList<Point>();
        points.add(new Point(107, 51));
        points.add(new Point(107, 645));
        sections.add(points);
        line = new GuiLine(sections, Bus1.IBUS1());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(544, 51));
        points.add(new Point(544, 645));
        sections.add(points);
        points = new ArrayList<Point>();
        points.add(new Point(546, 51));
        points.add(new Point(546, 645));
        sections.add(points);
        line = new GuiLine(sections, Bus1.IBUS2());
        gui.addLine(line);


        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(543, 100));
        points.add(new Point(378, 101));
        points.add(new Point(378, 175));
        sections.add(points);
        points = new ArrayList<Point>();
        points.add(new Point(378, 100));
        points.add(new Point(544, 100));
        sections.add(points);
        points = new ArrayList<Point>();
        points.add(new Point(378, 175));
        points.add(new Point(378, 101));
        sections.add(points);
        line = new GuiLine(sections, Bus1.IBUS2());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(377, 100));
        points.add(new Point(280, 100));
        points.add(new Point(280, 118));
        sections.add(points);
        line = new GuiLine(sections, IBUS2ToGPRAR.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(197, 129));
        points.add(new Point(203, 129));
        sections.add(points);
        line = new GuiLine(sections, Oper1.incGPRAR());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(203, 148));
        points.add(new Point(197, 148));
        sections.add(points);
        line = new GuiLine(sections, Oper1.ldGPRAR());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(357, 138));
        points.add(new Point(363, 138));
        sections.add(points);
        line = new GuiLine(sections, LogicalComponent.getCPUCLK());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(280, 158));
        points.add(new Point(280, 214));
        points.add(new Point(302, 214));
        sections.add(points);
        line = new GuiLine(sections, GPRAR.getOut(0));
        gui.addLine(line);


        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(455, 214));
        points.add(new Point(462, 214));
        sections.add(points);
        line = new GuiLine(sections, Oper1.wrGPR());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(378, 253));
        points.add(new Point(378, 280));
        points.add(new Point(445, 280));
        sections.add(points);
        line = new GuiLine(sections, GPRegs.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(458, 286));
        points.add(new Point(458, 291));
        sections.add(points);
        line = new GuiLine(sections, Oper1.GPRout2());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(469, 280));
        points.add(new Point(543, 280));
        sections.add(points);
        line = new GuiLine(sections, TSBGPRout2.getOut(0));
        gui.addLine(line);


        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(543, 318));
        points.add(new Point(359, 318));
        points.add(new Point(359, 336));
        sections.add(points);
        line = new GuiLine(sections, Bus1.IBUS2());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(276, 346));
        points.add(new Point(283, 346));
        sections.add(points);
        line = new GuiLine(sections, Oper1.incSP());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(276, 365));
        points.add(new Point(283, 365));
        sections.add(points);
        line = new GuiLine(sections, Oper1.decSP());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(436, 346));
        points.add(new Point(443, 346));
        sections.add(points);
        line = new GuiLine(sections, Oper1.ldSP());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(436, 365));
        points.add(new Point(443, 365));
        sections.add(points);
        line = new GuiLine(sections, LogicalComponent.getCPUCLK());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(359, 376));
        points.add(new Point(359, 403));
        points.add(new Point(203, 403));
        sections.add(points);
        line = new GuiLine(sections, SP.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(191, 409));
        points.add(new Point(191, 414));
        sections.add(points);
        line = new GuiLine(sections, Oper1.SPout1());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(181, 403));
        points.add(new Point(108, 403));
        sections.add(points);
        line = new GuiLine(sections, TSBSPout1.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(108, 601));
        points.add(new Point(246, 601));
        points.add(new Point(246, 584));
        sections.add(points);
        line = new GuiLine(sections, Bus1.IBUS1());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(163, 573));
        points.add(new Point(170, 573));
        sections.add(points);
        line = new GuiLine(sections, Oper1.ldCW());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(163, 554));
        points.add(new Point(170, 554));
        sections.add(points);
        line = new GuiLine(sections, LogicalComponent.getCPUCLK());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(246, 544));
        points.add(new Point(246, 526));
        points.add(new Point(322, 526));
        points.add(new Point(322, 508));
        sections.add(points);
        line = new GuiLine(sections, CW.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(543, 601));
        points.add(new Point(397, 601));
        points.add(new Point(397, 508));
        sections.add(points);
        line = new GuiLine(sections, Bus1.IBUS2());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(359, 468));
        points.add(new Point(359, 451));
        points.add(new Point(203, 451));
        sections.add(points);
        line = new GuiLine(sections, ADDadr.getOut(0));
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(191, 455));
        points.add(new Point(191, 462));
        sections.add(points);
        line = new GuiLine(sections, Oper1.ADDout1());
        gui.addLine(line);

        sections = new ArrayList<ArrayList<Point>>();
        points = new ArrayList<Point>();
        points.add(new Point(180, 450));
        points.add(new Point(108, 450));
        sections.add(points);
        line = new GuiLine(sections, TSBADDout1.getOut(0));
        gui.addLine(line);

        // LABELE:
        gui.addLabel(new GuiLabel(101, 46, Bus1.IBUS1()));
        gui.addLabel(new GuiLabel(101, 658, Bus1.IBUS1()));
        gui.addLabel(new GuiLabel(539, 46, Bus1.IBUS2()));
        gui.addLabel(new GuiLabel(539, 658, Bus1.IBUS2()));
        gui.addLabel(new GuiLabel(290, 115, IBUS2ToGPRAR.getOut(0)));
        gui.addLabel(new GuiLabel(285, 209, GPRAR.getOut(0)));
        gui.addLabel(new GuiLabel(385, 144, Bus1.IBUS2()));
        gui.addLabel(new GuiLabel(378, 293, GPRegs.getOut(0)));
        gui.addLabel(new GuiLabel(490, 275, TSBGPRout2.getOut(0)));
        gui.addLabel(new GuiLabel(368, 332, Bus1.IBUS2()));
        gui.addLabel(new GuiLabel(368, 403, SP.getOut(0)));
        gui.addLabel(new GuiLabel(132, 388, TSBSPout1.getOut(0)));
        gui.addLabel(new GuiLabel(132, 445, TSBADDout1.getOut(0)));
        gui.addLabel(new GuiLabel(370, 447, ADDadr.getOut(0)));
        gui.addLabel(new GuiLabel(220, 614, Bus1.IBUS1()));
        gui.addLabel(new GuiLabel(330, 525, CW.getOut(0)));
        gui.addLabel(new GuiLabel(405, 525, Bus1.IBUS2()));

    }

    public static Pin SP() {
        return SP.getOut(0);
    }

    public static Pin CW() {
        return CW.getOut(0);
    }

    public static Pin GPRAR() {
        return GPRAR.getOut(0);
    }

    public static int readGPR(int adress) {
        return GPRegs.read(adress);
    }

    public static GPR GPR() {
        return GPRegs;
    }

    public static REG RegGPRAR() {
        return GPRAR;
    }

    public static REG RegSP() {
        return SP;
    }

    public static REG RegCW() {
        return CW;
    }
}
